package net.nagaseyasuhito.nicola.service.impl;

import java.util.List;

import net.nagaseyasuhito.nicola.entity.Entry;
import net.nagaseyasuhito.nicola.entity.User;
import net.nagaseyasuhito.nicola.service.EntryService;

import com.wideplay.warp.persist.Transactional;

public class EntryServiceImpl extends BaseServiceImpl implements EntryService {
	@Override
	@Transactional
	public Entry findById(Long id) {
		String query = "from Entry where id = :id";
		return (Entry) this.createQuery(query)
			.setParameter("id", id)
			.getSingleResult();
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<Entry> findAllWithFriendsByUser(User user, int firstResult, int maxResults) {
		String query = "from Entry where user = :user or user in (select friend from User user join user.friends friend where user = :user) order by createTimestamp desc";
		return (List<Entry>) this.createQuery(query, firstResult, maxResults)
			.setParameter("user", user)
			.getResultList();
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<Entry> findAllByUser(User user, int firstResult, int maxResults) {
		String query = "from Entry where user = :user order by createTimestamp desc";
		return (List<Entry>) this.createQuery(query, firstResult, maxResults)
			.setParameter("user", user)
			.getResultList();
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<Entry> findAll(int firstResult, int maxResults) {
		String query = "from Entry order by createTimestamp desc";
		return (List<Entry>) this.createQuery(query, firstResult, maxResults)
			.getResultList();
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<Entry> findAllRepliesByUser(User user, int firstResult, int maxResults) {
		String query = "from Entry where (user = :user or user in (select friend from User user join user.friends friend where user = :user)) and content like '%@' || :userName || '%' order by createTimestamp desc";
		return (List<Entry>) this.createQuery(query, firstResult, maxResults)
			.setParameter("user", user)
			.setParameter("userName", user.getName())
			.getResultList();
	}

	@Override
	@Transactional
	public Entry findCurrentByUser(User user) {
		String query = "from Entry where user = :user order by createTimestamp desc";
		return (Entry) this.createQuery(query, 0, 1)
			.setParameter("user", user)
			.getSingleResult();
	}

	@Override
	@Transactional
	public long countAllWithFriendsByUser(User user) {
		String query = "select count(*) from Entry where user = :user or user in (select friend from User user join user.friends friend where user = :user)";
		return (Long) this.createQuery(query)
			.setParameter("user", user)
			.getSingleResult();
	}

	@Override
	@Transactional
	public long countAllByUser(User user) {
		String query = "select count(*) from Entry where user = :user";
		return (Long) this.createQuery(query)
			.setParameter("user", user)
			.getSingleResult();
	}

	@Override
	@Transactional
	public long countAll() {
		String query = "select count(*) from Entry";
		return (Long) this.createQuery(query)
			.getSingleResult();
	}

	@Override
	@Transactional
	public long countAllRepliesByUser(User user) {
		String query = "select count(*) from Entry where (user = :user or user in (select friend from User user join user.friends friend where user = :user)) and content like '%@' || :userName || '%'";
		return (Long) this.createQuery(query)
			.setParameter("user", user)
			.setParameter("userName", user.getName())
			.getSingleResult();
	}
	
	@Override
	@Transactional
	public void submit(Entry entry) {
		this.entityManager.persist(entry);
	}
}
